#include <iostream>
#include <cstdio>
#include <json/json.h>

#include "httplib.h"
#include "oj_model.hpp"
#include "oj_view.hpp"
#include "compile.hpp"
#include "tools.hpp"

int main()
{
    using namespace httplib;
    //1.初始化httplib库的server对象
    Server svr;
    ojModel model;

    //2.提供三个接口，分别处理三个请求
    //2.1获取整个试题列表   get
    svr.Get("/all_question",[&model](const Request& req,Response& resp)
            {
            //1.返回试题列表
            std::vector<Question> questions;
            model.GetAllQuestion(&questions);

            std::string html;
            OjView::DrawAllQuestions(questions,&html);
            resp.set_content(html,"text/html");
            });

    //2.2获取单个试题
    //如何标识浏览器想要获取的是哪个试题
    //\d:表示一位数字
    //\d+:表示OjView位数字
    svr.Get(R"(/question/(\d+))",[&model](const Request& req,Response& resp)
            {
                //1.获取url当中试题的数字和单个试题信息
                Question ques;
                model.GetOneQuestion(req.matches[1].str(),&ques);

                //2.渲染模板的html文件
                
                std::string html;
                OjView::DrawOneQuestion(ques,&html);
                resp.set_content(html,"text/html");
            });

    //2.3编译运行
    //
    svr.Post(R"(/compile/(\d+))",[&model](const Request& req,Response& resp)
            {
                //1.获取试题id和试题question
                Question ques;
                model.GetOneQuestion(req.matches[1].str(),&ques);

                std::unordered_map<std::string,std::string> body_map;
                UrlUtil::anaBody(req.body,&body_map);
                
                //构造json对象，交给编译运行模块
                Json::Value req_json;
                req_json["code"]=body_map["code"]+ques.tail_cpp_;
                std::cout<<req_json["code"].asString()<<std::endl;
                Json::Value resp_json;
                Compiler::CompileAndRun(req_json,&resp_json);

                //获取的返回结果都在resp_json当中
                std::string errorNo=resp_json["errorno"].asString();
                std::string com_ret=resp_json["reason"].asString();
                std::string case_ret=resp_json["stdout"].asString();
                std::string html;
                OjView::DrawCaseResult(errorNo,com_ret,case_ret,&html);
                resp.set_content(html,"text/html");
            });
    svr.set_base_dir("../bin/www");
    LOG(INFO,"hello")<<std::endl;
    svr.listen("0.0.0.0",12345);
    return 0;
}
